package com.starry.module.system.core.post.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.starry.core.common.constants.CommonError;
import com.starry.core.common.domain.vo.PageVo;
import com.starry.core.common.execption.ServiceException;
import com.starry.db.core.enums.DBEnableDisableStatusEnum;
import com.starry.db.core.query.LambdaQueryWrapperX;
import com.starry.module.system.api.post.domain.qo.SysPostPageQo;
import com.starry.module.system.api.post.domain.qo.SysPostQo;
import com.starry.module.system.api.post.domain.vo.SysPostDtlVo;
import com.starry.module.system.api.post.domain.vo.SysPostVo;
import com.starry.module.system.core.post.entity.SysPost;
import com.starry.module.system.core.post.mapper.SysPostMapper;
import com.starry.module.system.core.post.service.SysPostService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 系统岗位-服务实现
 *
 * @author xiaoke
 */
@Service("sysPostService")
public class SysPostServiceImpl implements SysPostService {

    private final SysPostMapper sysPostMapper;

    public SysPostServiceImpl(SysPostMapper sysPostMapper) {
        this.sysPostMapper = sysPostMapper;
    }

    @Override
    public PageVo<SysPostVo> page(SysPostPageQo pageQo) {
        PageVo<SysPost> page = sysPostMapper.selectPage(pageQo);
        List<SysPostVo> vos = BeanUtil.copyToList(page.getRows(), SysPostVo.class);
        return new PageVo<>(vos, page.getTotal());
    }

    @Override
    public SysPostDtlVo getById(Long id) {
        SysPost sysPost = sysPostMapper.selectById(id);
        if (sysPost == null) {
            throw new ServiceException(CommonError.DATA_NOT_EXISTS.getMsg());
        }
        return BeanUtil.toBean(sysPost, SysPostDtlVo.class);
    }

    @Transactional
    @Override
    public Long save(SysPostQo sysPostQo) {
        LambdaQueryWrapperX<SysPost> wrapper = new LambdaQueryWrapperX<>();
        //TODO 后端生成岗位编码
        wrapper
                .eq(SysPost::getName, sysPostQo.getName());
        if (sysPostMapper.selectCount(wrapper) > 0) {
            throw new ServiceException(CommonError.DATA_EXISTS.getMsg());
        }
        SysPost sysPost = BeanUtil.toBean(sysPostQo, SysPost.class);
        sysPost.setId(null);
        sysPostMapper.insert(sysPost);
        return sysPost.getId();
    }

    @Override
    public boolean existPostList(Set<Long> postIdList) {
        if (postIdList.isEmpty()) return true;
        LambdaQueryWrapperX<SysPost> queryWrapper = new LambdaQueryWrapperX<>();
        queryWrapper.in(SysPost::getId, postIdList);
        return sysPostMapper.selectCount(queryWrapper) == postIdList.size();
    }

    @Override
    public boolean exitsPostListStatus(Set<Long> postIdList) {
        if (postIdList.isEmpty()) return true;
        LambdaQueryWrapperX<SysPost> queryWrapperX = new LambdaQueryWrapperX<>();
        queryWrapperX
                .in(SysPost::getId, postIdList)
                .eq(SysPost::getStatus, DBEnableDisableStatusEnum.ENABLE.getCode());
        return sysPostMapper.selectCount(queryWrapperX) == postIdList.size();
    }

    @Override
    public List<SysPostVo> getByUserIdList(Long userId) {
        return sysPostMapper.selectByUserIdPostList(userId);
    }

    @Transactional
    @Override
    public void updateById(SysPostQo sysPostQo) {
        if (sysPostQo.getId() == null) {
            throw new ServiceException(CommonError.DATA_NOT_EXISTS.getMsg());
        }
        LambdaQueryWrapperX<SysPost> wrapper = new LambdaQueryWrapperX<>();
        wrapper
                .ne(SysPost::getId, sysPostQo.getId())
                .and(w ->
                        w.eq(SysPost::getName, sysPostQo.getName())
                );
        if (sysPostMapper.selectCount(wrapper) > 0) {
            throw new ServiceException(CommonError.DATA_EXISTS.getMsg());
        }
        SysPost sysPost = sysPostMapper.selectById(sysPostQo.getId());
        if (sysPost == null) {
            throw new ServiceException(CommonError.DATA_NOT_EXISTS.getMsg());
        }
        BeanUtil.copyProperties(sysPostQo, sysPost);
        sysPostMapper.updateById(sysPost);
    }

    @Transactional
    @Override
    public void removeByIds(Set<Long> idList) {
        if (idList.isEmpty()) return;
        List<SysPost> postList = sysPostMapper.selectByIdsIsUsePost(idList);
        if (!postList.isEmpty()) {
            List<String> codes = postList.stream()
                    .map(SysPost::getCode)
                    .toList();
            throw new ServiceException(String.format("岗位编号%s正在被使用，无法执行删除操作", codes));
        }
        sysPostMapper.deleteByIds(idList);
    }

    @Transactional
    @Override
    public void enable(Set<Long> idList) {
        if (idList.isEmpty()) return;
        sysPostMapper.updateBatch(setPostStatus(idList, DBEnableDisableStatusEnum.ENABLE));
    }

    @Transactional
    @Override
    public void disable(Set<Long> idList) {
        if (idList.isEmpty()) return;
        sysPostMapper.updateBatch(setPostStatus(idList, DBEnableDisableStatusEnum.DISABLE));
    }

    @Override
    public List<SysPostVo> findList(SysPostPageQo pageQo) {
        List<SysPost> sysPosts = sysPostMapper.selectPostList(pageQo);
        return BeanUtil.copyToList(sysPosts, SysPostVo.class);
    }

    private Set<SysPost> setPostStatus(Set<Long> idList, DBEnableDisableStatusEnum status) {
        Set<SysPost> sysPosts = new HashSet<>();
        idList.forEach(item -> {
            SysPost sysPost = new SysPost();
            sysPost.setId(item);
            sysPost.setStatus(status.getCode());
            sysPosts.add(sysPost);
        });
        return sysPosts;
    }


}

